<template>
  <div>
    <!-- 面包屑 -->
    <el-breadcrumb separator="/">
      <el-breadcrumb-item :to="{ path: '/layout' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item><a>文章管理</a></el-breadcrumb-item>
      <el-breadcrumb-item>文章发布</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 卡片组件 -->
    <el-card>
      <!-- 
            表单组件
            model: 表单数据对象	
            label-width: 表示label的宽度
         -->
      <el-form ref="form" :model="form" label-width="80px">
        <!-- label: 表示标题（标签文本） -->
        <el-form-item label="标题:">
          <el-input v-model="form.title"></el-input>
        </el-form-item>
        <!-- 类型 -->
        <el-form-item label="类型:">
          <el-radio-group @change="typeChange" v-model="form.type">
            <!-- v-bind绑定可以将字符串数字变量变为数字 -->
            <el-radio :label="1">文章</el-radio>
            <el-radio :label="2">视频</el-radio>
          </el-radio-group>
        </el-form-item>
        <!-- 内容 -->

        <el-form-item label="内容:">
          <!-- 富文本编辑器
              使用vue-word-editor插件
              使用地址：官方：https://github.com/hsian/vue-word-editor
              https://blog.csdn.net/yupyuping/article/details/109524903
         -->
          <VueEditor v-show="form.type == 1" :config="config" ref="vueEditor" />
          <!-- 视频上传
              1 配置请求地址 :action的值
              2 配置请求头 headers
              3 视频上传成功后，保存视频的链接
              4 删除视频，清空content的值
              5 上传视频数量超出限制，提示用户
           -->
          <el-upload
            v-show="form.type == 2"
            :action="baseURL + '/upload'"
            :headers="headers"
            :limit="1"
            :on-success="videoSuccess"
            :on-remove="videoRemove"
            :on-exceed="videoExeed"
            :file-list="videoFile"
          >
            <el-button size="small" type="primary">点击上传</el-button>
            <div slot="tip" class="el-upload__tip">只能上传视频文件</div>
          </el-upload>
        </el-form-item>
        <!-- 栏目 -->
        <el-form-item label="栏目">
          <el-checkbox
            :indeterminate="isIndeterminate"
            v-model="checkAll"
            @change="handleCheckAllChange"
            >全选</el-checkbox
          >
          <div style="margin: 15px 0"></div>
          <el-checkbox-group
            v-model="checkedCategory"
            @change="handleCheckedCitiesChange"
          >
            <el-checkbox
              v-for="item in category"
              :key="item.id"
              :label="item.id"
              name="type"
              >{{ item.name }}</el-checkbox
            >
          </el-checkbox-group>
        </el-form-item>
        <!-- 封面 -->
        <el-form-item label="封面">
          <el-upload
            :action="baseURL + '/upload'"
            :headers="headers"
            :on-success="coverSuccess"
            :on-remove="coverRemove"
            :limit="3"
            :on-exceed="coverExceed"
            :file-list="form.cover"
            list-type="picture-card"
          >
            <i class="el-icon-plus"></i>
          </el-upload>
        </el-form-item>
        <!-- 发布 -->

        <el-button type="primary" @click="publishFn">发布文章</el-button>
      </el-form>
    </el-card>
  </div>
</template>


<script>
/* 渲染栏目接口
  1 封装接口函数
  2 在文章发布页面引入函数，并在create调用函数获取栏目
  3 根据数据进行渲染
*/
import { getCategory } from "@/api/common.js";
import { publish, articleDetail, post_update } from "@/api/article.js";
// 引入富文本编辑器相关文件
import VueEditor from "vue-word-editor";
import "quill/dist/quill.snow.css";
import axios from "@/util/request";
// console.log(axios.defaults.baseURL);
export default {
  components: { VueEditor },
  data() {
    return {
      baseURL: axios.defaults.baseURL, // 基础地址
      headers: { Authorization: localStorage.getItem("token_backend") },
      checkAll: false, //栏目全选控制
      isIndeterminate: false, // 表示全选框的不确定状态
      checkedCategory: [], // 小选框选中集合
      category: [], // 所有栏目集合
      videoFile: [], // 视频上传文件列表
      form: {
        title: "", // 文章标题
        content: "", // 文章内容
        categories: [], // 所属栏目ID集合
        cover: [], // 封面图片ID集合
        type: 1, // 类型 1是文章 2是视频
      },
      config: {
        // 上传图片的配置
        uploadImage: {
          url: axios.defaults.baseURL + "/upload", //文章上传到服务器端的处理路径
          name: "file", //后台所需要的参数的名称
          headers: this.getToken(), //设置请求头信息
          // res是结果，insert方法会把内容注入到编辑器中，res.data.url是资源地址
          uploadSuccess(res, insert) {
            // console.log(142, res);
            insert(axios.defaults.baseURL + res.data.data.url); //文件上传之后的回调，接收服务器响应回来的数据，根据服务器的地址进行填充
          },
        },
      },
    };
  },
  created() {
    // 获取栏目列表
    getCategory().then((res) => {
      // console.log(res);
      // 排除关注、头条两条栏目
      // 关注是要用户关注作者才有，头条默认所有属性都有，因此不需要参与发表文章
      this.category = res.data.data.slice(2);
    });

    const id = this.$route.query.id;
    console.log(157, id);
    // 判断有id时，说明是编辑文章，才需调用articleDetail请求
    if (id) {
      articleDetail(id).then((res) => {
        console.log("获取详情", res);
        // 标题回显
        this.form.title = res.data.data.title;
        // 类型回显
        this.form.type = res.data.data.type;
        // 内容回显
        if (this.form.type == 1) {
          // 回显富文本的内容
          const quill = this.$refs.vueEditor.editor;
          quill.clipboard.dangerouslyPasteHTML(0, res.data.data.content);
          // this.form.content = res.data.data.content; // 这里发布文章会获取到赋值
        } else {
          // 回显视频
          this.videoFile = [
            {
              name: "小视频",
              url: res.data.data.content,
            },
          ];
          this.form.content = res.data.data.content;
        }
        // 栏目回显
        this.checkedCategory = res.data.data.categories.map((item) => item.id);
        // 判断栏目中的全选框的不确定状态
        this.isIndeterminate =
          this.checkedCategory.length != this.category.length &&
          this.checkedCategory.length
            ? true
            : false;

        // 封面回显 使用file-list属性上传方式可将内容重新渲染上
        this.form.cover = res.data.data.cover.map((item) => {
          // 判断原本的url是否是完整地址
          const url =
            item.url.indexOf("http") == -1 ? this.baseURL + item.url : item.url;
          return {
            name: "封面",
            url: url,
            id: item.id,
          };
        });
      });
    }
  },
  methods: {
    // 类型改变的时候，清空内容
    typeChange() {
      // console.log(224);
      this.form.content = "";
      this.videoList = [];
    },
    // 视频上传超出限制的回调函数 提示用户
    videoExeed() {
      this.$message({
        message: "只能上传一条视频",
        type: "warning",
      });
    },
    // 视频移除的回调函数 删除conten的内容
    videoRemove() {
      this.form.content = "";
    },
    // 视频上传成功的回调函数
    videoSuccess(file) {
      // console.log(150, file);
      if (file.message == "文件上传成功") {
        this.form.content = file.data.url;
      }
    },
    // 封面上传图片超出限制数量的回调函数
    coverExceed() {
      this.$message({
        message: "温馨提示，封面最多上传3张!",
        type: "warning",
      });
    },
    // 封面移除的回调函数
    coverRemove(file, fileList) {
      console.log(file, fileList);
      // file:被删除的图片文件对象  fileList: 剩下未被删除的图片集合
      // 将剩下的图片重新赋值给cover
      this.form.cover = fileList.map((item) => {
        return { id: item.id, url: item.url };
      });
    },
    // 封面上传成功后的回调函数
    coverSuccess(res) {
      console.log("封面上传成功", res);
      // 需要把id包装成对象上传再push到数组中 后端规定的格式
      this.form.cover.push({
        id: res.data.id,
        url: this.baseURL + res.data.url,
      });
    },

    // 发布文章
    publishFn() {
      // 判断标题是否为空
      if (!this.form.title) {
        this.$message.warning("标题不能为空");
        return;
      }

      // 判断文章是什么类型1是文章 2是视频
      if (this.form.type == 1) {
        const quill = this.$refs.vueEditor.editor;
        // 文章就把富文本编辑的内容赋值给content
        this.form.content = quill.root.innerHTML;
        // 判断富文本内容是否为空
        /*
            当富文本内容为空时，默认会返回一个换行符，因此不能简单的判断内容是否为空
            使用一个方法getLength进行判断，当 getLength方法返回1的时候
         */
        const length = quill.getLength();
        if (length == 1) {
          this.$message.warning("富文本不能为空");
          return;
        }
      } else {
        // 判断视频是否为空
        if (!this.form.content) {
          this.$message.warning("视频不能为空");
          return;
        }
      }
      // 栏目判断
      if (this.checkedCategory.length == 0) {
        this.$message.warning("栏目不能为空");
        return;
      }
      // 封面判断
      if (this.form.cover.length == 0) {
        this.$message.warning("封面不能为空");
        return;
      }

      // 数据处理 将[1,2,3] => [{id:1}{id:2}]
      this.form.categories = this.checkedCategory.map((item) => {
        return { id: item };
      });
      console.log("form表单", this.form);

      // 编辑文章
      const id = this.$route.query.id;
      // 判断是否有id存在，有则编辑  ---因为这里新增和编辑都使用同一个articleAdd.vue
      if (id) {
        post_update(id, this.form).then((res) => {
          console.log("编辑", res);
          if (res.data.message == "文章编辑成功") {
            this.$router.push("/layout/articleList");
            this.$message.success(res.data.message);
            return;
          }
          this.$message.console.error(res.data.message);
        });

        // 编辑成功 退出函数
        return;
      }

      // 新增文章
      publish(this.form).then((res) => {
        console.log("发布成功", res);
        if (res.data.message == "文章发布成功") {
          this.$router.push("/layout/articleList");
          this.$message.success(res.data.message);
          return;
        }
        this.$message.console.error(res.data.message);
      });
    },

    // 全选控制
    handleCheckAllChange(val) {
      // 根据全选框的状态值，把checkedCategory赋值为全部栏目id的集合表示全部选中，空数组表示取消全选
      this.checkedCategory = val ? this.category.map((item) => item.id) : [];
      this.isIndeterminate = false; // false 表示确定状态
    },
    // 单选控制
    handleCheckedCitiesChange(value) {
      // value:表示选中的选项集合
      // 设置全选框的不确定状态 isIndeterminate值为true表示不确定状态 当value长度不等于全部栏目长度和value长度为空设置为false
      this.isIndeterminate =
        value.length != this.category.length && value.length ? true : false;
      // 判断value长度的是否等于全部栏目长度，于此判断全选框的选中
      this.checkAll = value.length == this.category.length ? true : false;
    },
    getToken() {
      return {
        Authorization: localStorage.getItem("token_backend"),
      };
    },
  },
};
</script>


<style lang="less" scoped>
.el-card {
  margin-top: 20px;
}
</style>